package com.ishare.common.aop;

import com.ishare.common.base.BaseEntity;
import com.ishare.common.constant.ParamConstans;
import com.ishare.common.entity.po.SysUser;
import com.ishare.common.utils.InternalUserUtil;
import com.ishare.common.utils.RequestUtil;
import com.ishare.common.utils.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;

/**
 * @description: 自动处理参数
 * @author: DENGMINGWEN
 * @time: 2020/8/10 10:01
 */
@Aspect
@Component
public class ParamsAspect {

    private final static Logger log = LoggerFactory.getLogger(ParamsAspect.class);

    @Pointcut("execution(public * com.ishare.*.controller.*.*(..))")
    public void pointcut(){}

    /**请求参数**/
    @Before("pointcut()")
    public Object req(JoinPoint joinPoint){
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                .getRequest();
        String url = request.getRequestURL().toString();
        String method = request.getMethod();
        String uri = request.getRequestURI();
        String params = request.getQueryString();
        log.info("请求开始，请求携带参数： url：{}，method: {},uri:{},params:{}",url,method,uri,params);
        if (!StringUtils.isBlank(uri) && uri.contains("login")){
            return joinPoint;
        }
        String uid = String.valueOf(((SysUser)SecurityUtils.getSubject().getPrincipal()).getId());
        String ip = RequestUtil.getIpAddress(request);
        BaseEntity baseEntity = new BaseEntity(uid,uid,new Date(),new Date(),ip,ip,1);
        InternalUserUtil.setInternalUser(baseEntity);
        return joinPoint;
    }

    /***
     * @description: 数据保存定义切面
     * @author: DENGMINGWEN
     * @time: 2020/8/10 10:39
     */
    @Pointcut("execution(public * com.ishare.*.controller.*.insert*(..)) || execution(public * com.ishare.*.controller.*.save*(..))")
    public void insertPointcut(){}

    /***
     * @description: 数据修改定义切面
     * @author: DENGMINGWEN
     * @time: 2020/8/10 10:39
     */
    @Pointcut("execution(public * com.ishare.*.controller.*.update*(..)) || execution(public * com.ishare.*.controller.*.delete*(..)) || execution(public * com.ishare.*.controller.*.remove*(..))")
    public void updatePointcut(){}

    @Before("insertPointcut()")
    public void insertBefore(JoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        if (args !=null && args.length>0){
            refineParams(args[0],ParamConstans.CREATE_BY,ParamConstans.CREATE_TIME,ParamConstans.CREATE_IP,ParamConstans.STATUS);
        }
    }

    @Before("updatePointcut()")
    public void updateBefore(JoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        if (args !=null && args.length>0){
            refineParams(args[0], ParamConstans.UPDATE_BY,ParamConstans.UPDATE_TIME,ParamConstans.UPDATE_IP);
        }
    }

    /**
     * @description: 批量参数注入
     * @author: DENGMINGWEN
     * @time: 2021/3/18 17:31
     */
    private void refineParams(Object argment,String...args){
        log.info("开始批量参数注入...");
        BaseEntity internalUser = (BaseEntity) InternalUserUtil.getInternalUser();
        BeanWrapperCustomize beanWrapper;
        if (argment instanceof List){
            //数组
            List argList = (List) argment;
            for (Object o : argList) {
                beanWrapper = new BeanWrapperCustomize(o);
                for (String arg : args) {
                    beanWrapper.setProperty(internalUser,arg);
                }
            }
        }else {
            //对象
            for (String arg : args) {
                beanWrapper = new BeanWrapperCustomize(argment);
                beanWrapper.setProperty(internalUser,arg);
            }
        }
    }
}
